From 869f21ee2efaefed6a5aa4fbd417c25df8dec02a Mon Sep 17 00:00:00 2001 From: soryu Date: Sun, 18 Jan 2026 17:44:50 +0000 Subject: Add React Native mobile app for Makima (#3) * [WIP] Heartbeat checkpoint - 2026-01-18 02:58:27 UTC * feat(mobile): complete mobile app integration and verification - Add ThemeColors type export to Colors.ts for type safety - Export SUPABASE_URL from supabase.ts and use environment variables - Update .env.example with correct default URLs - Add comprehensive README.md with setup instructions Verified: - TypeScript compiles without errors - App exports successfully for iOS and Android - All screens accessible (login, dashboard, tasks, settings, task detail) - Auth flow working with Zustand store and Supabase Co-Authored-By: Claude Opus 4.5 * Task completion checkpoint --------- Co-authored-by: Claude Opus 4.5 --- apps/mobile/app/task/[id].tsx | 259 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 apps/mobile/app/task/[id].tsx (limited to 'apps/mobile/app/task/[id].tsx') diff --git a/apps/mobile/app/task/[id].tsx b/apps/mobile/app/task/[id].tsx new file mode 100644 index 0000000..121063a --- /dev/null +++ b/apps/mobile/app/task/[id].tsx @@ -0,0 +1,259 @@ +import React from 'react'; +import { + View, + Text, + StyleSheet, + ScrollView, + useColorScheme, + ActivityIndicator, +} from 'react-native'; +import { useLocalSearchParams, Stack } from 'expo-router'; +import { Colors } from '../../constants/Colors'; +import { useTask } from '../../hooks/useTasks'; +import { TaskStatusBadge } from '../../components/TaskStatusBadge'; +import { EmptyState } from '../../components/EmptyState'; + +export default function TaskDetailScreen() { + const colorScheme = useColorScheme() ?? 'light'; + const colors = Colors[colorScheme]; + const { id } = useLocalSearchParams<{ id: string }>(); + + const { data: task, isLoading, isError } = useTask(id); + + if (isLoading) { + return ( + <> + + + + + + ); + } + + if (isError || !task) { + return ( + <> + + + + + + ); + } + + return ( + <> + + + {/* Header */} + + + + + + {task.name} + + {task.description && ( + + {task.description} + + )} + + + {/* Progress Summary */} + {task.progressSummary && ( + + + Progress + + + {task.progressSummary} + + + )} + + {/* Task Info */} + + + Details + + + + + Created + + + {new Date(task.createdAt).toLocaleString()} + + + + {task.startedAt && ( + + + Started + + + {new Date(task.startedAt).toLocaleString()} + + + )} + + {task.completedAt && ( + + + Completed + + + {new Date(task.completedAt).toLocaleString()} + + + )} + + {task.repositoryUrl && ( + + + Repository + + + {task.repositoryUrl} + + + )} + + + {/* Subtasks */} + {task.subtasks && task.subtasks.length > 0 && ( + + + Subtasks ({task.subtasks.length}) + + {task.subtasks.map((subtask) => ( + + + + {subtask.name} + + + ))} + + )} + + {/* Error message */} + {task.errorMessage && ( + + + Error + + {task.errorMessage} + + )} + + {/* Placeholder for future features */} + + + Task output and controls will be added here + + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + }, + centered: { + justifyContent: 'center', + alignItems: 'center', + }, + content: { + padding: 16, + gap: 16, + }, + header: { + padding: 16, + borderRadius: 12, + gap: 8, + }, + headerTop: { + flexDirection: 'row', + justifyContent: 'flex-start', + }, + taskName: { + fontSize: 20, + fontWeight: '700', + }, + description: { + fontSize: 14, + lineHeight: 20, + }, + section: { + padding: 16, + borderRadius: 12, + gap: 12, + }, + sectionTitle: { + fontSize: 16, + fontWeight: '600', + }, + progressText: { + fontSize: 14, + lineHeight: 20, + }, + infoRow: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + }, + infoLabel: { + fontSize: 14, + }, + infoValue: { + fontSize: 14, + fontWeight: '500', + flex: 1, + textAlign: 'right', + marginLeft: 16, + }, + subtaskRow: { + flexDirection: 'row', + alignItems: 'center', + gap: 8, + paddingVertical: 4, + }, + subtaskName: { + fontSize: 14, + flex: 1, + }, + errorSection: { + backgroundColor: '#fee2e2', + }, + errorText: { + fontSize: 14, + color: '#991b1b', + lineHeight: 20, + }, + placeholder: { + padding: 32, + alignItems: 'center', + }, + placeholderText: { + fontSize: 14, + textAlign: 'center', + }, +}); -- cgit v1.2.3